Skip to content

Fix rotate_app_creds YAML parsing when from_yaml returns a list#19

Merged
imatza-rh merged 2 commits into
mainfrom
fix-ocp-creds-yaml-parsing
Jul 2, 2026
Merged

Fix rotate_app_creds YAML parsing when from_yaml returns a list#19
imatza-rh merged 2 commits into
mainfrom
fix-ocp-creds-yaml-parsing

Conversation

@tusharjadhav3302

@tusharjadhav3302 tusharjadhav3302 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Fix the rotate_app_creds day2ops procedure failing at the credential verification step with:
'list object' has no attribute 'clouds'

Why

The to_nice_yaml(indent=4) filter prepends ---\n to the clouds.yaml content. When this content is piped into the OCP openstack-credentials secret via oc set data, the secret stores the YAML document separator. On readback, Ansible's from_yaml interprets the ----prefixed content as a multi-document YAML and returns a list (with one element) instead of a dict.
The verification assert then fails because it expects ocp_creds.clouds.openstack.auth_type but ocp_creds is a list, not a mapping.

What failed

Task: Verify credentials rotated to application credentials
Error from Zuul job (shiftstack-rhel9-rhoso18.0-ocp421, Jun 30):
The conditional check 'ocp_creds.clouds.openstack.auth_type == 'v3applicationcredential'' failed. The error was: error while evaluating conditional (ocp_creds.clouds.openstack.auth_type == 'v3applicationcredential'): 'list object' has no attribute 'clouds'. 'list object' has no attribute 'clouds'

Note: The credential rotation itself succeeds — the secret IS correctly updated. Only the verification readback parsing fails.

How

Two fixes applied to rotate_app_creds.yml:

1. Prevention — strip --- before writing to the secret:

# Before (buggy):
cat {{ clouds_yaml_file_path }} | sed 's/{{ user_cloud }}:/openstack:/' | \
oc set data -n kube-system secret/openstack-credentials clouds.yaml=-

# After (fixed):
cat {{ clouds_yaml_file_path }} | sed '/^---$/d' | sed 's/{{ user_cloud }}:/openstack:/' | \
oc set data -n kube-system secret/openstack-credentials clouds.yaml=-

2. Defensive parsing — handle both list and dict from from_yaml:

# Before (buggy):
- name: Parse OCP credentials
  ansible.builtin.set_fact:
    ocp_creds: "{{ ocp_creds_output.stdout | from_yaml }}"

# After (fixed):
- name: Parse OCP credentials
  vars:
    parsed_yaml: "{{ ocp_creds_output.stdout | from_yaml }}"
  ansible.builtin.set_fact:
    ocp_creds: "{{ (parsed_yaml is mapping) | ternary(parsed_yaml, parsed_yaml[0]) }}"

Test Plan

  • ansible-lint passes (production profile)
  • Day2ops rotation passes on a running OCP cluster
  • oc get secret -n kube-system openstack-credentials content has no leading ---
  • ocp_creds correctly parsed as dict with auth_type: v3applicationcredential

References

Bug: https://redhat.atlassian.net/browse/OCPBUGS-95045
Parent feature: https://redhat.atlassian.net/browse/OSPRH-6485
Failing job: shiftstack-rhel9-rhoso18.0-ocp421 periodic run (Jun 30, 2026)

@tusharjadhav3302 tusharjadhav3302 added the ready-for-review PR is ready for code review label Jul 1, 2026

@imatza-rh imatza-rh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm. Two things, please:

  1. Rebase on main - #20 is merged, so the cherry-picked install-config commit is already on main. A rebase should drop it cleanly.

  2. Testing - could you check the test plan boxes or link a CI run showing the rotation succeeds with the fix?

@tusharjadhav3302 tusharjadhav3302 force-pushed the fix-ocp-creds-yaml-parsing branch from a04c57b to 9d8bbb0 Compare July 2, 2026 05:46
@tusharjadhav3302

Copy link
Copy Markdown
Contributor Author

On running the ansible playbook manually on a healthy shiftstack cluster over serval71 using the following command :
sh-5.2$ ansible-navigator run playbooks/ocp_testing.yaml \ --extra-vars '{"stages": ["day2ops"], "day2ops_procedures": ["rotate_app_creds"], "installation_type": "ipi"}' \ -m stdout

The execution passes :
PLAY RECAP ********************************************************************* localhost : ok=191 changed=40 unreachable=0 failed=0 skipped=65 rescued=0 ignored=0

The failing ansible task now shows passing :
TASK [shiftstack.stages.day2ops : Verify credentials rotated to application credentials] *** ok: [localhost] => { "changed": false, "msg": "Credential rotation verified — auth_type is v3applicationcredential" }

A zuul ci re-run is triggered for the ci-framework-testproject

@tusharjadhav3302

Copy link
Copy Markdown
Contributor Author

tusharjadhav3302 and others added 2 commits July 2, 2026 20:24
The clouds.yaml stored in the OCP secret starts with '---' (from
to_nice_yaml), causing from_yaml to return a list instead of a dict.
Strip the document separator before piping to the secret and handle
both list/dict cases when parsing the verification readback.

OSPRH-6485

Co-authored-by: Cursor <cursoragent@cursor.com>
…sibility

The previous from_yaml fix handled the list case but not the string
case. The root cause is the jq + base64 pipeline returning unexpected
content. Switch to oc get -o jsonpath for reliable raw value extraction,
add debug output to diagnose future parsing issues, and improve the
assert to show actual values on failure.

OCPBUGS-95045

Co-authored-by: Cursor <cursoragent@cursor.com>

@dlaw4608 dlaw4608 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!!

@imatza-rh imatza-rh merged commit 736ee2b into main Jul 2, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-review PR is ready for code review

Development

Successfully merging this pull request may close these issues.

3 participants